/**
*  \file tasklet.h
*
*  \brief   Administration of light-weight tasks.
*
*  \author  Michael J. Hohmann <michael.hohmann@linde-mh.de>
*  \author Francesco D'Aprea <francesco.daprea@linde-mh.de>
*
*  The module tasklet provide the ability to organize callback like functions
*  in a double linked lists.
*/
#ifndef TASKLET_H_INCLUDED
#define TASKLET_H_INCLUDED

/*================================================[ public includes  ]================================================*/
#include "..\cfg\prj.h"
#include "..\list\list.h"
#include "..\cfg\tasklet_cfg.h"

/*================================================[ public defines   ]================================================*/

/** Get pointer to data. */
#define TASKLET_DATA(arg)   LIST_DATA(arg)->data

/*================================================[ public datatypes ]================================================*/
struct tasklet; /* forward declaration */

/** Function pointer type.
*
* Type of the callback functions stored in each tasklet_task .
*/
typedef void (*tasklet_function_t) (struct tasklet *task);

/** Time emitter function */
typedef tasklet_time_t (*tasklet_timer_function_t)(void);

/** Function Callback Item.
*
* Each instance of tasklet_task can store on function callback pointer and a data pointer, to be linked
* to an tasklet list.
*
*/
struct tasklet_data
{
   tasklet_function_t function;    /**< Function pointer */
   void * data;                    /**< Data will passed to the function */
   tasklet_time_t  tasklet_time;   /**< Maximum Process time */
};

/** Tasklet Struct Definition */
LIST_NODE_STRUCT( tasklet, struct tasklet_data ) ;

/** Task_list Struct Definition */
struct tasklet_list
{
   tasklet_timer_function_t timer_function; /**< Pointer to a time giving function.*/
   tasklet_time_t           process_time;   /**< Maximum time the tasklet list has needed to be executed. */
   volatile OBSERVER_TYPE observer;                   /**< will be cleared to 0 if slice has completed */
   LIST_HEAD_STRUCT( tasklet_head, struct tasklet ) tasklet_list;
} ;

/*================================================[ public variables ]================================================*/

/*================================================[ public functions ]================================================*/

/** Initialize head element.
*
*  The function tasklet_list_initialize() will initialize the head element of a tasklist.
*  It is important to initialize a list object before the call of any other function.
*  After the call of tasklet_initialize() the list will be empty.
*
*  \param list Pointer to the head object.
*
*  \param timer_function Time after which the tasklet is excecuted.
*
*  \return Pointer to the initialized head object.
*/
struct tasklet_list * tasklet_list_initialize( struct tasklet_list *list, tasklet_timer_function_t timer_function );


/** Initialize tasklet and join it to a tasklet list.
*
*  The function tasklet_assign() initializes the passed tasklet struct
*  and link it to the end of the also passed tasklet list.
*  It is save to pass NULL for head,item or function, but then the tasklet is not linked to the tasklet list.
*
*  \param list       Pointer to the head element of list.
*
*  \param task       Pointer to a tasklet struct.
*
*  \param func   Pointer to the function which should be associated with the tasklet.
*
*  \param data       User data. Can be set to arbitrarily content.
*
*  \return           Pointer to the assigned tasklet if successful, or NULL if tasklet was not assigned.
*/
struct tasklet* tasklet_assign( struct tasklet_list *list, struct tasklet *task, tasklet_function_t func, void* data );


/** Execute tasklets.
*
*  The function tasklet_perform() execute all tasklets that are currently associated to the list.
*
*  \param head    Pointer to the a head element of a tasklet list.
*
*  \return        Number of called tasklets.
*/
U16 tasklet_perform( struct tasklet_list *head  );

/*================================================[ inline functions ]================================================*/

/** Get Process Time
*
* \param list Pointer to an exisiting list element. Its not save to pass NULL.
*
* \return Maximum time consumption of all tasklets in the list.
*/
STATIC_INLINE tasklet_time_t tasklet_get_process_time( struct tasklet_list *list )
{
   return list->process_time;
}

/** Clear process time
*
* Set maximum process time to 0, and return the current time.
*
* \param list Pointer to an existing list element. Its not save to pass NULL.
* \return Maximum time consumption of all tasklets in the list.
*/
STATIC_INLINE tasklet_time_t tasklet_clear_process_time( struct tasklet_list *list )
{
   tasklet_time_t rv;
   rv= list->process_time;
   list->process_time =0 ;
   return rv;
}

/** Get Tasklet Time
*
* \param task Pointer to an exisiting list element. Its not save to pass NULL.
* \return Maximum time consumption of the passed tasklet.
*/
STATIC_INLINE tasklet_time_t tasklet_get_tasklet_time( struct tasklet *task )
{
   return LIST_DATA(task)->tasklet_time;
}

/** Clear Tasklet Time
*
* Set the maximum tasklet time to 0, and return the current tasklet time.
*
* \param task Pointer to an existing list element. Its not save to pass NULL.
* \return Maximum time consumption of the passed tasklet.
*/
STATIC_INLINE tasklet_time_t tasklet_clear_tasklet_time( struct tasklet *task )
{
   tasklet_time_t rv;
   rv= LIST_DATA(task)->tasklet_time;
   LIST_DATA(task)->tasklet_time = 0;
   return rv;
}

/** Monitor Execution.
*
*  The function tasklet_obeserver() can be used to monitor the execution of the attached tasklets.
*
*  \param list Object pointer.
*  \param call_max Maximum execution of the observer function.
*
*  \return TRUE if number of calls is less or equal than the passed value, otherwise FALSE.
*/
STATIC_INLINE BO tasklet_observer( struct tasklet_list *list, OBSERVER_TYPE call_max )
{
   RC rv =  list->observer <= call_max ;

   if( OBSERVER_MAX != list->observer) /* prevent overrun */
   {
      list->observer++;
   }

   return rv;
}

/*====================================================================================================================*/

#endif
/***********************************************************************************************************************
*                             Copyright 2009,2011 Linde Material Handling. All rights reserved.                        *
***********************************************************************************************************************/
